/*
 * 文  件   名： HttpActionBase.java
 * 版          权： Copyright GoPawPaw All Rights Reserved.
 * 描          述：[该类的简要描述]
 * 创  建   人： LiJinHua
 * 创建时间： 2012-4-12
 * 
 * 修   改  人：
 * 修改时间：
 * 修改内容：[修改内容]
 */
package app.http.action;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import app.http.HttpConnector;
import app.http.HttpHelper;
import app.http.HttpListener;
import app.http.HttpRequest;
import app.http.HttpResponse;
import app.log.AppLog;
import app.paser.JsonParser;
import app.paser.ParserInterface;
import app.utils.CommonUtils;
import app.utils.FileUtil;


/**
 * Http请求基类
 * 
 * @author LiJinHua
 * @date 2012-4-12
 * @version [Android 1.0.0, 2012-4-12]
 * @description
 */
public class HttpActionBase implements HttpListener {

	/**
	 * TAG
	 */
	private static final String TAG = HttpActionBase.class.getSimpleName();

	/**
	 * 显示提示信息
	 */
	public static final int MSG_SHOW_ALERTDIALOG = 101;

	/**
	 * 发送请求的Activity
	 */
	private Activity activity;

	/**
	 * 回调接口
	 */
	private HttpActionListener httpActionListener;

	/**
	 * 解析器类
	 */
	private Class<?> parserClass = JsonParser.class;
	
	/**
	 * 解析器对象
	 */
	private ParserInterface mParser;
	
	/**
	 * [构造简要说明]
	 * 
	 * @param httpActionListener
	 */
	public HttpActionBase(HttpActionListener httpActionListener,
			Activity activity) {

		this.httpActionListener = httpActionListener;
		this.activity = activity;

		HttpHelper.setResources(activity);
	}

	/**
	 * 发送RUL请求
	 * 
	 * @param urlId
	 */
	public void sendRequest(int urlId) {
		sendRequest(urlId, 0, this, null, false);
	}

	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param connectionId 请求链接Id
	 */
	public void sendRequest(int urlId,int connectionId) {
		sendRequest(urlId, connectionId, this, null, false);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param paramObj 请求参数字典
	 */
	public void sendRequest(int urlId,Object paramObj) {
		sendRequest(urlId, 0, this, paramObj, false);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param paramObj 请求参数字典
	 * @param urlId
	 * @param paramObj
	 * @param requestMethod HttpRequest.REQUEST_METHOD_GET HttpRequest.REQUEST_METHOD_POST
	 */
	public void sendRequest(int urlId,Object paramObj,String requestMethod) {
		sendRequest(urlId, 0, this, paramObj, false,requestMethod);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param paramObj 请求参数字典
	 * @param urlId
	 * @param paramObj
	 * @param requestMethod HttpRequest.REQUEST_METHOD_GET HttpRequest.REQUEST_METHOD_POST
	 */
	public void sendRequest(int urlId,int connectionId,Object paramObj,String requestMethod) {
		sendRequest(urlId, connectionId, this, paramObj, false,requestMethod);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param connectionId 请求链接Id
	 * @param paramObj 请求参数字典
	 */
	public void sendRequest(int urlId,int connectionId,Object paramObj) {
		sendRequest(urlId, connectionId, this, paramObj, false);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId 请求UrlId
	 * @param connectionId 请求链接Id
	 * @param paramObj 请求参数字典
	 * @param remove 在请求之前清空请求队列
	 */
	public void sendRequest(int urlId,int connectionId,Object paramObj,boolean remove) {
		sendRequest(urlId, connectionId, this, paramObj, remove,HttpRequest.REQUEST_METHOD_GET);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId
	 *            请求UrlId
	 * @param connectionId
	 *            请求链接Id
	 * @param httpListener
	 *            请求监听器
	 * @param paramObj
	 *            请求参数字典
	 * @param remove
	 *            在请求之前清空请求队列
	 */
	private void sendRequest(int urlId, int connectionId,
			HttpListener httpListener, Object paramObj, boolean remove){
		sendRequest(urlId, connectionId, this, paramObj, remove,HttpRequest.REQUEST_METHOD_GET);
	}
	
	/**
	 * 发送URL请求
	 * @param urlId
	 *            请求UrlId
	 * @param connectionId
	 *            请求链接Id
	 * @param httpListener
	 *            请求监听器
	 * @param paramObj
	 *            请求参数字典
	 * @param remove
	 *            在请求之前清空请求队列
	 */
	private void sendRequest(int urlId, int connectionId,
			HttpListener httpListener, Object paramObj, boolean remove,String requestMethod) {
		Object object = null;
		object = HttpActionDataCache.getCache(urlId, connectionId);
		if (object != null) {
			// 数据从缓存取，直接返回给页面
			onFinish(object, urlId, connectionId);
			return;
		} else {
			// 缓存不存在数据，则发送Http请求数据

		}

		if (!CommonUtils.isNetworkAvailable(activity)) {
			AppLog.e(TAG, "网络不可用");

			String errMsg = "当前网络不可用，请检查您的网络链接！";
			showErrorMsg(errMsg);

			httpActionListener.onHttpActionResponse(
					HttpActionListener.STATE_FAILED, null, urlId, connectionId);

			return;
		}

		int mode = HttpRequest.REQUEST_MODE_3;

		if (remove) {
			// 清空请求队列
			mode = HttpRequest.REQUEST_MODE_1;
		}

		String url = HttpHelper.getUrlById(urlId);
		String data = HttpHelper.getRequestURLParam(paramObj, urlId);

		// 创建新的请求
		HttpRequest request = new HttpRequest(url, data, httpListener, mode,
				HttpRequest.REQUEST_TYPE_1, requestMethod);
		request.setUrlId(urlId);
		request.setConnectionId(connectionId);

		// 发送Http请求
		HttpConnector.sendHttpRequest(request);

	}

	/**
	 * 读取缓存数据后，向请求页面回调数据
	 * 
	 * @param data
	 * @param urlId
	 * @param connectionId
	 */
	protected void onFinish(Object data, int urlId, int connectionId) {

		int state = HttpActionDataCache.getCacheState(urlId, connectionId);

		httpActionListener.onHttpActionResponse(state, data, urlId,
				connectionId);

	}

	@Override
	public void httpResponse(HttpResponse httpResponse) {
		// TODO Auto-generated method stub

		AppLog.d(TAG,
				"Code:" + httpResponse.getResponseCode() + "Type:"
						+ httpResponse.getContentType() + "Length:"
						+ httpResponse.getContentLength());

		Object data = null;
		if (httpResponse.getResponseCode() == HttpResponse.RESPONSE_CODE_SUCCESS) {
			// Http返回成功
			InputStream is = httpResponse.getInputStream();

			byte[] bs = null;
			try {
				bs = FileUtil.readStream(is);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			int errCode = HttpActionListener.STATE_SUCCESS;
			if(bs == null){
				//数据读取失败
				AppLog.e(TAG, "数据读取失败");

				String errMsg = "数据读取失败，请稍候再试！";
				showErrorMsg(errMsg);
				errCode = HttpActionListener.STATE_FAILED;
				
				actionResponse(errCode, data, httpResponse
						.getHttpRequest().getUrlId(), httpResponse.getHttpRequest()
						.getConnectionId());
				return;
			}
			
			if (AppLog.IS_DEBUG) {
				// 调试模式下，打印出服务器返回的报文
				AppLog.d(TAG, new String(bs));
			}

			//进行数据解析
			data = actionParse(bs);

			if (data == null) {
				// 数据解析失败
				AppLog.e(TAG, "数据解析失败");

				String errMsg = "数据请求失败，请稍候再试！";
				showErrorMsg(errMsg);
				errCode = HttpActionListener.STATE_FAILED;
			} else {
				// 获取错误码
//				String errMsg = "OK。。。";
//				showErrorMsg(errMsg);
				if(mParser != null){
					errCode = mParser.checkErrorCode(data, httpResponse.getHttpRequest()
							.getUrlId());
				}else{
					errCode = HttpActionListener.STATE_FAILED;
				}
				
				if (errCode == HttpActionListener.STATE_SUCCESS) {
					//错误码是成功，则对数据进行缓存
					HttpActionDataCache.saveToCache(httpResponse
							.getHttpRequest().getUrlId(), httpResponse.getHttpRequest()
							.getConnectionId(), data,
							httpResponse.getHttpRequest().getParamData(), errCode);
				}
			}

			actionResponse(errCode, data, httpResponse
						.getHttpRequest().getUrlId(), httpResponse.getHttpRequest()
						.getConnectionId());
			
		} else {
			// Http错误返回
			String errMsg = "数据请求失败，请检查您的网络设置！";
			showErrorMsg(errMsg);
			
			actionResponse(
						HttpActionListener.STATE_FAILED, data, httpResponse
						.getHttpRequest().getUrlId(), httpResponse
						.getHttpRequest().getConnectionId());
			
		}
	}

	/**
	 * 执行响应
	 * @param state
	 * @param data
	 * @param urlId
	 * @param connectionId
	 */
	private void actionResponse(int state, Object data, int urlId, int connectionId){
		if(activity != null || !activity.isFinishing()){
			//当前的activity还存在时，则回调
			httpActionListener.onHttpActionResponse(
					state, data, urlId, connectionId);
		}
	}
	
	/**
	 * 执行解析
	 * 
	 * @param bs
	 */
	private Object actionParse(byte[] bs) {
		Object data = null;
		try {
			Object obj = parserClass.newInstance();
			if(obj instanceof ParserInterface){
				mParser = (ParserInterface)obj;
				mParser.actionParse(bs);
				data = mParser.getData();
			}else{
				AppLog.e(TAG, "找不到解析器");
			}
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return data;
	}
	
	/**
	 * 框架统一消息弹出处理交互Handler对象
	 */
	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case MSG_SHOW_ALERTDIALOG:
//				String errMsg = (String) msg.obj;
//				DialogUtils.showAlertDialog(activity,errMsg);
//				Toast.makeText(activity, errMsg, Toast.LENGTH_SHORT).show();
				break;

			default:
				break;
			}
		}

	};

	/**
	 * 
	 * [框架统一提示信息弹出方法]<BR>
	 * 
	 * @param errMsg
	 *            错误提示信息
	 */
	private void showErrorMsg(String errMsg) {
		Message msg = new Message();
		msg.what = MSG_SHOW_ALERTDIALOG;
		if (errMsg == null || "".equals(errMsg)) {
			return;
		}
		msg.obj = errMsg;
		mHandler.sendMessage(msg);
	}

	public void setParserClass(Class<?> parserClass) {
		this.parserClass = parserClass;
	}

}
